package com.valuedaas.schoolsafety.service.recources;

import com.alibaba.fastjson.JSON;
import com.mongodb.Block;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.Projections;
import com.mongodb.client.model.Updates;
import com.valuedaas.schoolsafety.common.collects.sys.SysInterface;
import com.valuedaas.schoolsafety.common.collects.sys.SysMenu;
import com.valuedaas.schoolsafety.common.collects.sys.SysRole;
import com.valuedaas.schoolsafety.common.collects.sys.SysUser;
import com.valuedaas.schoolsafety.common.enums.DataStatus;
import com.valuedaas.schoolsafety.controller.resource.vo.InterfaceVO;
import com.valuedaas.schoolsafety.controller.user.vo.User;
import com.valuedaas.schoolsafety.service.BaseService;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class InterfaceService extends BaseService {
    @Override
    protected String collName() {
        return SysInterface.COLL_NAME;
    }

    /**
     * 获得授权菜单所有的接口
     *
     * @param menuIds 菜单ID
     * @return 接口列表
     */
    public List<Document> getInterfaceByMenu(List<ObjectId> menuIds) {
        List<Document> interfaces = new ArrayList<>();
        mongoTemplate.getCollection(collName()).find(
                new Document("menuId", new Document("$in", menuIds)).append("status", DataStatus.NORMAL))
                .into(interfaces);

        Map<ObjectId, String> nameMap = new HashMap<ObjectId, String>();

        mongoTemplate.getCollection(SysMenu.COLL_NAME).find(Filters.in(SysMenu._ID, menuIds))
                .projection(Projections.include(SysMenu.NAME)).forEach(new Block<Document>() {
            @Override
            public void apply(Document t) {
                nameMap.put(t.getObjectId(SysMenu._ID), t.getString(SysMenu.NAME));
            }
        });

        for (Document d : interfaces) {
            d.put("menuName", nameMap.get(d.getObjectId(SysInterface.MENUID)));
        }

        return interfaces;
    }

    /**
     * 新增加一个接口
     *
     * @param interfacevo
     */
    public void add(InterfaceVO interfacevo) {
        Document doc = Document.parse(JSON.toJSONString(interfacevo));
        doc.remove(SysInterface._ID);
        doc.put(SysInterface.MENUID, new ObjectId(interfacevo.getMenuId()));
        mongoTemplate.getCollection(collName()).insertOne(doc);
    }

    /**
     * 逻辑删除一个接口
     *
     * @param id
     * @return
     */
    public boolean delete(String id) {
        return mongoTemplate.getCollection(collName()).updateOne(Filters.eq(SysInterface._ID, new ObjectId(id)),
                Updates.set(SysInterface.STATUS, DataStatus.DELETE)).getModifiedCount() > 0;
    }

    /**
     * 更新某个接口信息
     *
     * @param interfaceDoc
     * @return
     */
    public boolean update(InterfaceVO interfaceVO) {
        Document doc = Document.parse(JSON.toJSONString(interfaceVO));
        doc.remove(SysInterface._ID);
        doc.put(SysInterface.MENUID, new ObjectId(interfaceVO.getMenuId()));
        return mongoTemplate.getCollection(collName())
                .updateOne(Filters.eq(SysInterface._ID, new ObjectId(interfaceVO.get_id())), new Document("$set", doc))
                .getMatchedCount() > 0;
    }

    /**
     * 获取某个接口详细信息
     *
     * @param id
     * @return
     */
    public Document get(String id) {
        return mongoTemplate.getCollection(collName()).find(new Document(SysInterface._ID, new ObjectId(id))
                .append(SysInterface.STATUS, DataStatus.NORMAL)).first();
    }

    /**
     * 获得用户授权的接口ID列表
     *
     * @param userId 用户ID
     * @return 接口ID列表
     */
    @SuppressWarnings("unchecked")
    public List<String> getUserInterfaceIds(String userId) {
        List<String> list = new ArrayList<String>();

        Document document = mongoTemplate.getCollection(SysUser.COLL_NAME)
                .find(new Document(SysUser._ID, new ObjectId(userId))).projection(new Document(SysUser.ROLES, 1)
                        .append(SysUser.UNITID, 1).append(SysUser.USERNAME, 1).append(SysUser.INTERFACES, 1))
                .first();
        if (document != null) {
            // 获取该用户拥有的所有角色的 所有接口
            List<ObjectId> roles = (List<ObjectId>) document.get(SysUser.ROLES);
            if (roles != null) {
                mongoTemplate.getCollection(SysRole.COLL_NAME).find(new Document(SysRole._ID, new Document("$in", roles)))
                        .projection(new Document(SysRole.INTERFACES, 1)).forEach(new Block<Document>() {
                    @Override
                    public void apply(Document t) {
                        List<ObjectId> interfaceList = (List<ObjectId>) t.get(SysRole.INTERFACES);
                        if (interfaceList != null) {
                            for (ObjectId id : interfaceList) {
                                list.add(id.toString());
                            }
                        }
                    }
                });
            }

            // 获取该用户 特别接口
            List<ObjectId> interfaces = (List<ObjectId>) document.get(SysUser.INTERFACES);
            interfaces.forEach((i) -> list.add(i.toString()));
        }
        return list;
    }

    /**
     * 获取用户拥有的所有接口 信息
     *
     * @param user
     * @return
     */
    public List<Document> getUserAuthedInterface(User user) {
        List<Document> result = new ArrayList<>();
        List<String> interfaceIdList = this.getUserInterfaceIds(user.getUserId());
        mongoTemplate.getCollection(collName())
                .find(new Document(SysInterface._ID, new Document("$in", interfaceIdList)).append(SysInterface.STATUS,
                        DataStatus.NORMAL))
                .into(result);
        return result;
    }

    /**
     * 设置用户授权接口资源
     *
     * @param userId     用户ID
     * @param interfaces 接口ID集合
     */
    public void setUserAuthInterface(String userId, Collection<String> interfaces) {
        Document filter = new Document("_id", new ObjectId(userId.getBytes()));

        List<ObjectId> interfaceIdList = new ArrayList<>();
        for (String str : interfaces) {
            interfaceIdList.add(new ObjectId(str));
        }

        mongoTemplate.getCollection(SysUser.COLL_NAME).updateOne(filter, Updates.set(SysUser.INTERFACES, interfaces));
    }

//    /**
//     * 根据资源url获取资源详情
//     *
//     * @param uri
//     * @param params
//     * @return
//     */
//    public Document findInterface(String uri, String params) {
//        return mongoTemplate.getCollection(collName())
//                .find(new Document(SysInterface.URL, uri).append(SysInterface.STATUS, DataStatus.NORMAL))
//                .first();
//
//    }

    /**
     * 根据资源url获取资源详情
     *
     * @param url
     * @return
     */
    public Document findInterface(String url) {
        return mongoTemplate.getCollection(collName())
                .find(new Document(SysInterface.URL, url).append(SysInterface.STATUS, DataStatus.NORMAL.name()))
                .first();
    }

    /**
     * 判断用户对资源是否有访问权限
     * @param user
     * @param interfaceId
     * @return
     */
    public boolean accessAuth(User user, String interfaceId) {
        if(user.getUsername().equals("admin")){
            return true;
        }
        // 授权接口
        List<String> authedInterfaces = this.getUserInterfaceIds(user.getUserId());
        if (authedInterfaces.contains(interfaceId)) {
            return true;
        }
        return false;
    }
}